﻿@page "/traces"
@page "/traces/resource/{applicationName}"

@using Aspire.Dashboard.Otlp.Model
@using Aspire.Dashboard.Resources
@using Aspire.Dashboard.Utils
@using System.Globalization
@using Aspire.Dashboard.Components.Controls.Grid
@inject IJSRuntime JS
@inject IStringLocalizer<Dashboard.Resources.Traces> Loc
@inject IStringLocalizer<ControlsStrings> ControlsStringsLoc
@implements IDisposable

<PageTitle><ApplicationName ResourceName="@nameof(Dashboard.Resources.Traces.TracesPageTitle)" Loc="@Loc" /></PageTitle>

<div class="page-content-container">
    <AspirePageContentLayout AddNewlineOnToolbar="true" @ref="@_contentLayout">
        <PageTitleSection>
            <h1 class="page-header">@Loc[nameof(Dashboard.Resources.Traces.TracesHeader)]</h1>
        </PageTitleSection>
        <ToolbarSection>
            <ResourceSelect Resources="_applicationViewModels"
                            AriaLabel="@ControlsStringsLoc[nameof(ControlsStrings.SelectAnApplication)]"
                            @bind-SelectedResource="PageViewModel.SelectedApplication"
                            @bind-SelectedResource:after="HandleSelectedApplicationChanged"
                            CanSelectGrouping="true" />
            <FluentSearch @bind-Value="_filter"
                          @oninput="HandleFilter"
                          @bind-Value:after="HandleAfterFilterBindAsync"
                          Placeholder="@ControlsStringsLoc[nameof(ControlsStrings.FilterPlaceholder)]"
                          title="@Loc[nameof(Dashboard.Resources.Traces.TracesNameFilter)]"
                          slot="end" />
        </ToolbarSection>
        <MainSection>
            <div class="datagrid-overflow-area continuous-scroll-overflow" tabindex="-1">
                <GridColumnManager @ref="_manager" Columns="@_gridColumns">
                    <FluentDataGrid ResizeLabel="@AspireFluentDataGridHeaderCell.GetResizeLabel(ControlsStringsLoc)"
                                    ResizeType="DataGridResizeType.Discrete"
                                    Virtualize="true"
                                    GenerateHeader="GenerateHeaderOption.Sticky"
                                    ItemSize="46"
                                    ResizableColumns="true"
                                    ItemsProvider="@GetData"
                                    TGridItem="OtlpTrace"
                                    GridTemplateColumns="@_manager.GetGridTemplateColumns()"
                                    ShowHover="true"
                                    OnRowClick="@(r => r.ExecuteOnDefault(d => NavigationManager.NavigateTo(DashboardUrls.TraceDetailUrl(d.TraceId))))"
                                    Class="enable-row-click">
                        <ChildContent>
                            <AspireTemplateColumn ColumnId="@TimestampColumn" ColumnManager="@_manager" Title="@ControlsStringsLoc[nameof(ControlsStrings.TimestampColumnHeader)]" TooltipText="@(context => FormatHelpers.FormatDateTime(TimeProvider, context.FirstSpan.StartTime, MillisecondsDisplay.Full, CultureInfo.CurrentCulture))" Tooltip="true">
                                @FormatHelpers.FormatTimeWithOptionalDate(TimeProvider, context.FirstSpan.StartTime, MillisecondsDisplay.Truncated)
                            </AspireTemplateColumn>
                            <AspireTemplateColumn ColumnId="@NameColumn" ColumnManager="@_manager" Title="@ControlsStringsLoc[nameof(ControlsStrings.NameColumnHeader)]" Tooltip="true" TooltipText="@(trace => GetNameTooltip(trace))">
                                <span style="padding-left:5px; border-left-width: 5px; border-left-style: solid; border-left-color: @(ColorGenerator.Instance.GetColorHexByKey(GetResourceName((context.RootSpan ?? context.FirstSpan).Source)));">
                                    <FluentHighlighter HighlightedText="@(TracesViewModel.FilterText)" Text="@(context.FullName)" />
                                </span>
                                <span class="trace-id">@OtlpHelpers.ToShortenedId(context.TraceId)</span>
                            </AspireTemplateColumn>
                            <AspireTemplateColumn ColumnId="@SpansColumn" ColumnManager="@_manager" Title="@Loc[nameof(Dashboard.Resources.Traces.TracesSpansColumnHeader)]">
                                <FluentOverflow>
                                    <ChildContent>
                                        @foreach (var item in context.Spans.GroupBy(s => s.Source.Application).OrderBy(g => g.Min(s => s.StartTime)))
                                        {
                                            <FluentOverflowItem>
                                                <span class="trace-tag trace-service-tag" title="@(GetSpansTooltip(item))" style="border-left-color: @(ColorGenerator.Instance.GetColorHexByKey(GetResourceName(item.Key)));">
                                                    @if (item.Any(s => s.Status == OtlpSpanStatusCode.Error))
                                                    {
                                                        <FluentIcon Icon="Icons.Filled.Size12.ErrorCircle" Color="Color.Error" Class="trace-tag-icon" />
                                                    }
                                                    @GetResourceName(item.Key) (@item.Count())
                                                </span>
                                            </FluentOverflowItem>
                                        }
                                    </ChildContent>
                                    <MoreButtonTemplate Context="overflow">
                                        <span class="trace-tag">
                                            @($"+{overflow.ItemsOverflow.Count()}")
                                        </span>
                                    </MoreButtonTemplate>
                                    <OverflowTemplate Context="overflow">
                                        @{
                                            var items = overflow.ItemsOverflow.ToList();
                                        }
                                        <FluentTooltip UseTooltipService="false" Anchor="@overflow.IdMoreButton">
                                            @foreach (var item in items)
                                            {
                                                <div style="margin-top: 8px; margin-bottom: 8px;">
                                                    @item.ChildContent
                                                </div>
                                            }
                                        </FluentTooltip>
                                    </OverflowTemplate>
                                </FluentOverflow>
                            </AspireTemplateColumn>
                            <AspireTemplateColumn ColumnId="@DurationColumn" ColumnManager="@_manager" Title="@ControlsStringsLoc[nameof(ControlsStrings.DurationColumnHeader)]">
                                <div class="duration-container">
                                    @if (ViewportInformation.IsDesktop)
                                    {
                                        <FluentProgressRing Class="duration-ring"
                                                            Min="0"
                                                            Max="@Convert.ToInt32(TracesViewModel.MaxDuration.TotalMilliseconds)"
                                                            Value="@Convert.ToInt32(context.Duration.TotalMilliseconds)"
                                                            aria-label="@ControlsStringsLoc[nameof(ControlsStrings.DurationColumnHeader)]" />
                                        <span class="trace-duration">
                                            @DurationFormatter.FormatDuration(context.Duration)
                                        </span>
                                    }
                                    else
                                    {
                                        @DurationFormatter.FormatDuration(context.Duration)
                                    }
                                </div>
                            </AspireTemplateColumn>
                            <AspireTemplateColumn ColumnId="@DetailsColumn" ColumnManager="@_manager" Title="@ControlsStringsLoc[nameof(ControlsStrings.DetailsColumnHeader)]" Class="no-ellipsis">
                                <FluentAnchor Appearance="Appearance.Lightweight" Href="@DashboardUrls.TraceDetailUrl(context.TraceId)" @onclick:stopPropagation="true">@ControlsStringsLoc[nameof(ControlsStrings.ViewAction)]</FluentAnchor>
                            </AspireTemplateColumn>
                        </ChildContent>
                        <EmptyContent>
                            <FluentIcon Icon="Icons.Regular.Size24.GanttChart" />&nbsp;@Loc[nameof(Dashboard.Resources.Traces.TracesNoTraces)]
                        </EmptyContent>
                    </FluentDataGrid>
                </GridColumnManager>
            </div>
        </MainSection>
        <FooterSection>
            <TotalItemsFooter @ref="_totalItemsFooter" />
        </FooterSection>
    </AspirePageContentLayout>
</div>
